/**
 * @author Akos Szabo - Axi - aaszabo@gmail.com
 * Dec 12, 2011
 * 
 * Implements com.axi.ga.IDns interface.
 * This is required by the ResPlanGa.
 * This does most of the job in GA. IT creates, evaluates, crosses DNSs.
 */
package com.axi.resplan;

import java.util.Hashtable;
import java.util.Random;

import com.axi.ga.IDns;


public class ResPlanDns implements IDns 
{

	
	String _dns;
	
	TimeTable _tt;
	
	int _fitness;
	
	
	public ResPlanDns(TimeTable argTimeTable)
	{
		_tt = argTimeTable;
		createDnsString();
	}
	
	
	public ResPlanDns()
	{
		
	}
	
//INTERFACE Methods	
	
	/* (non-Javadoc)
	 * @see com.axi.ga.IDns#getDns()
	 */
	@Override
	public IDns getDns() 
	{
		// TODO Auto-generated method stub
		return this;
	}

	/* (non-Javadoc)
	 * @see com.axi.ga.IDns#getFitness()
	 */
	@Override
	public int getFitness() 
	{
		// TODO Auto-generated method stub
		return _fitness;
	}

	

	/* (non-Javadoc)
	 * @see com.axi.ga.IDns#mutate()
	 */
	@Override
	public void mutate() 
	{
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see com.axi.ga.IDns#compare(com.axi.ga.IDns)
	 */
	@Override
	public int compare(IDns argDns) 
	{
		// TODO Auto-generated method stub
		
		if(argDns.getFitness() == _fitness)		
			return 0;
		
		if(argDns.getFitness() > _fitness)		
			return 1;
		
		return -1;	
		
	}
	

	public IDns clone()
	{
		ResPlanDns res = new ResPlanDns();
		res._tt = this._tt;
		res._dns = this._dns.toString();
		res._fitness = this._fitness;
		return res;
	}
	 
	
	private void createDnsString()
	{
		Random rndR = new Random();
		Random rndN = new Random();
		
		int tNum = _tt.getTaskList().size();

		
		//HOGY nézzen ki a DNS???
		//egy string 
		//szakaszkból áll
		//a szakaszok feladatoknak felelnek meg
		//az első szakasz az első feladaté, a második a másodiké és így tovább
		//egy szakasz leírja, hogy kinek a feladata és annak az erőforrásnak ez hanyadik feladata
		//A feladat tulajdonosát egy (esetleg 2) byte azonosítja. A szám adja meg, hogy melyik erőforrásé a feladat:
		// szam%rscNum, vagyis a szám maradékos osztása határozza meg.
		//a sorrendet két byte-on írja le egy számláló.
		//a sorrend nem zárt sorszámozású. A nagyobb szám jön késöbb.
		
		StringBuffer sb = new StringBuffer();
		
		for(int i=0; i<tNum; i++)
		{
			//one cycle creates a section
			//one section contains the resource id on the first byte
			//and the task order of that given resource
			//the first section is for the first task, the second is the second, etc.

			//add the resource first
			//later here can the preset of resource be handled
			sb.append( genetize( rndR.nextInt(256),1 ) );
			//sb.append(':');
			//add the order	of task. This could be a bigger range if required
			sb.append( genetize( rndN.nextInt(256),1 ) );
			//sb.append('|');
		}
		_dns = sb.toString();		
	}
	
	
	/**
	 * Format the gene by extending it with leading zeros.
	 * @param argData
	 * @param argByteSize
	 * @return
	 */
	private String genetize(int argData, int argByteSize)
	{
		// this solution is for one byte only
		String zr = "00000000";
		String res = Integer.toBinaryString(argData);
		res = zr.substring(res.length()) + res;
				
		return res;
	}
	
	
		
	public String toString()
	{
		//String str;
		//int maxResource = _tt.getResourceVector().size();
		
		return _dns.toString();
	}
	
	
}
